package com.jade.bss.ec.ware.impl;

import java.util.List;

import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.jade.bss.ec.ware.Ware;
import com.jade.bss.ec.ware.WareDao;
import com.jade.bss.ec.ware.WareException;
import com.jade.bss.ec.ware.WareSku;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.Group;
import com.jade.framework.base.criterion.sql.SqlUtils;
import com.jade.framework.base.util.PagingList;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;

/**
 * 商品数据访问接口。
 */
@Named ("bss_wareDao")
public class JpaWareDao
        implements WareDao
{
    protected static final String SQL_WARE = "SELECT ware FROM com.jade.bss.ec.ware.Ware ware";
    protected static final String SQL_SKU = "SELECT sku FROM com.jade.bss.ec.ware.WareSku sku";
    @PersistenceContext (unitName = "default")
    protected EntityManager entityManager;

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.g", key = "#ware.id"),
            @CacheEvict (value = "bss.ec.ware.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.q", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.scat", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sbrand", allEntries = true)})
    public void addWare(Ware ware)
            throws WareException
    {
        entityManager.persist(ware);
    }

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.g", key = "#ware.id"),
            @CacheEvict (value = "bss.ec.ware.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.q", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.scat", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sbrand", allEntries = true)})
    public void updateWare(Ware ware)
            throws WareException
    {
        entityManager.merge(ware);
    }

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.g", key = "#ware.id"),
            @CacheEvict (value = "bss.ec.ware.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.q", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.scat", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sbrand", allEntries = true)})
    public void removeWare(Ware ware)
            throws WareException
    {
        Ware old = getWare(ware.getId());
        if (old != null) {
            entityManager.remove(old);
        }
    }

    @Cacheable (value = "bss.ec.ware.g", key = "#id")
    public Ware getWare(long id)
            throws WareException
    {
        return entityManager.find(Ware.class, id);
    }

    @Cacheable (value = "bss.ec.ware.l", key = "#criteria")
    public List<Ware> listWare(Criteria criteria)
    {
        return SqlUtils.sqlQueryWithoutCount(SQL_WARE, entityManager, criteria);
    }

    @Cacheable (value = "bss.ec.ware.q", key = "#criteria")
    public PagingList<Ware> queryWare(Criteria criteria)
    {
        return SqlUtils.sqlQuery(SQL_WARE, entityManager, criteria);
    }

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.sku.g", key = "#sku.id"),
            @CacheEvict (value = "bss.ec.ware.sku.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sku.q", allEntries = true)})
    public void addSku(WareSku sku)
            throws WareException
    {
        entityManager.persist(sku);
    }

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.sku.g", key = "#sku.id"),
            @CacheEvict (value = "bss.ec.ware.sku.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sku.q", allEntries = true)})
    public void updateSku(WareSku sku)
            throws WareException
    {
        entityManager.merge(sku);
    }

    @Caching (evict = {@CacheEvict (value = "bss.ec.ware.sku.g", key = "#sku.id"),
            @CacheEvict (value = "bss.ec.ware.sku.l", allEntries = true),
            @CacheEvict (value = "bss.ec.ware.sku.q", allEntries = true)})
    public void removeSku(WareSku sku)
            throws WareException
    {
        WareSku old = getSku(sku.getId());
        if (old != null) {
            entityManager.remove(old);
        }
    }

    @Cacheable (value = "bss.ec.ware.sku.g", key = "#id")
    public WareSku getSku(long id)
    {
        return entityManager.find(WareSku.class, id);
    }

    @Cacheable (value = "bss.ec.ware.sku.l", key = "#criteria")
    public List<WareSku> listSku(Criteria criteria)
    {
        return SqlUtils.sqlQueryWithoutCount(SQL_SKU, entityManager, criteria);
    }

    @Cacheable (value = "bss.ec.ware.sku.q", key = "#criteria")
    public PagingList<WareSku> querySku(Criteria criteria)
    {
        return SqlUtils.sqlQuery(SQL_SKU, entityManager, criteria);
    }

    @Cacheable (value = "bss.ec.ware.sbrand", key = "#criteria")
    public List<Long> searchBrand(Criteria criteria)
    {
        String sql = "SELECT brandId FROM com.jade.bss.ec.ware.Ware ware";
        Group group = new Group();
        group.addGroup("ware", "brandId");
        criteria.setGroup(group);
        return SqlUtils.sqlQueryWithoutCount(sql, entityManager, criteria);
    }

    @Cacheable (value = "bss.ec.ware.scat", key = "#criteria")
    public List<Long> searchCategory(Criteria criteria)
    {
        String sql = "SELECT cid FROM com.jade.bss.ec.ware.Ware ware";
        Group group = new Group();
        group.addGroup("ware", "cid");
        criteria.setGroup(group);
        return SqlUtils.sqlQueryWithoutCount(sql, entityManager, criteria);
    }
}
